\section{XML Driving Directions Schema}

\begin{quote}
Continuing Exercise 2.2, write a schema for your driving directions XML language using the following schema languages:
(a) DTD 
(b) XML schema
\end{quote}

\subsection{DTD}
Here we present the DTD schema definition for the directionXML language. There are a list of limitations in the application of the DTD schema however few are met in this simple example of a DTD schema. 

The DTD schema is pretty straightforward beginning with the list of primary elements; the start of the driving directions followed by end adress, total estimated time and distance, and finally a list of more complexly defined directionspoints. 

The driving directions consists of a varying number of different types of actions such as startOutGoing or mergeOnto. A more detailed description of these types are found in the next subsection regarding the XML schema.

\begin{lstlisting}
<!ELEMENT DrivingDirection (
	  start, 
	  end,
	  totalEstTime, 
	  totalEstDistance, 
	  directionPoint*)>
<!ELEMENT start (EMPTY)>
<!ATTLIST start 
	  address CDATA #REQUIRED
	  state CDATA #REQUIRED
	  zip CDATA #REQUIRED
	  country CDATA #REQUIRED>
<!ELEMENT end (EMPTY)>
<!ATTLIST end 
	  address CDATA #REQUIRED
	  state CDATA #REQUIRED
	  zip CDATA #REQUIRED
	  country CDATA #REQUIRED>
<!ELEMENT totalEstTime (EMPTY)>
<!ATTLIST totalEstTime 
	  hours CDATA #REQUIRED
	  minutes CDATA #REQUIRED>
<!ELEMENT totalEstDistance (EMPTY)>
<!ATTLIST totalEStDistance
	  length CDATA #REQUIRED>
<!ELEMENT directionPoint (
	  startOutGoing*, 
	  on*, 
	  toward*, 
	  turnLeftOnto*, 
	  turnRightOnto*,
	  becomes*,
	  mergeOnto*,
	  via*,
	  take*,
	  turnSlightRightOnto*,
	  turnSlightLeftOnto*,
	  takeThe*)>
<!ATTLIST directionPoint
	  length CDATA #REQUIRED>
<!ELEMENT startOutGoing (#PCDATA)>
<!ELEMENT on (#PCDATA)>
<!ELEMENT toward (#PCDATA)>
<!ELEMENT turnLeftOnto (#PCDATA)>
<!ELEMENT turnRightOnto (#PCDATA)>
<!ELEMENT becomes (
	  before,
	  after)>
<!ELEMENT before (#PCDATA)>
<!ELEMENT after (#PCDATA)>
<!ELEMENT mergeOnto (#PCDATA)>
<!ELEMENT via (#PCDATA)>
<!ELEMENT take (#PCDATA)>
<!ELEMENT turnSlightRightOnto (#PCDATA)>
<!ELEMENT turnSlightLeftOnto (#PCDATA)>
<!ELEMENT takeThe (ramp, exit, toward)>
<!ELEMENT ramp (EMPTY)>
<!ELEMENT exit (#PCDATA)>
\end{lstlisting}

\subsection{XML schema}

We will now give XML schema definition of the directionML. In the root element \texttt{schema} we specify the default namespace to be the 2003 standard XMLSchema. As the unique URI that specifies the targetNamespace we imagine we can use the path \texttt{dWebTek/directionML} on the \texttt{www.daimi.au.dk/} server. We also specify that we can use this namespace with the prefix \texttt{d:}. 

The root element of our directionML is \texttt{drivingDirection}, which is a complex type containing one \texttt{start}, \texttt{end}, \texttt{totalEstTime} and \texttt{totalEstDistance} element and a series of \texttt{directionPoint} elements. 

The first four elements are complex types but contains only some string type attributes. The last \texttt{directionPoint} elements contains a number of descriptive elements like \texttt{startOutGoing}, \texttt{turnLeftOnto} and \texttt{toward}. These can in theory be combined in any order, but there are of course some implicit constraints. For example there should be exactly one \texttt{startOutGoing} element placed topmost and \texttt{towards} should only be placed after some direction like \texttt{turnLeftOnto}, but realizing these constraints would resolve in a lot of different \texttt{directionPoint} elements and too complicated relations. In this case we place our trust in simplicity. 

When a road has several names like 'PA-36/N MAIN ST' we specify this by using the same element several times in a row like \texttt{<startOutGoing>NORTHWEST</startOutGoing><on>PA-36</on><on>N MAIN ST</on>}.

\begin{lstlisting}
<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:d="http://www.daimi.au.dk/dWebTek/directionML" 
    targetNamespace="http://www.daimi.au.dk/dWebTek/directionML">
  <element name="drivingDirection" type="d:drivingDirectionType"/>
  <element name="start" type="d:startType"/>
  <element name="end" type="d:endType"/>
  <element name="totalEstTime" type="d:totalEstTimeType"/>
  <element name="totalEstDistance" type="d:totalEstDistanceType"/>
  <element name="directionPoint" type="d:directionPointType"/>
  
  <element name="startOutGoing" type="string"/>
  <element name="on" type="string"/>
  <element name="turnLeftOnto" type="string"/>
  <element name="turnRightOnto" type="string"/>
  <element name="turnSlightLeftOnto" type="string"/>
  <element name="turnSlightRightOnto" type="string"/>
  <element name="mergeOnto" type="string"/>
  <element name="becomes" type="d:becomesType"/>
  <element name="takeThe" type="d:takeTheType"/>
  <element name="toward" type="string"/>
  <element name="via" type="string"/>
  <element name="continueToFollow" type="string"/>
  <element name="endAt" type="string"/>

  <complexType name="drivingDirectionType">
    <sequence>
      <element ref="d:start"/>
      <element ref="d:end"/>
      <element ref="d:totalEstTime"/>
      <element ref="d:totalEstDistance"/>
      <element ref="d:directionPoint" maxOccurs="unbounded"/>
    </sequence>
  </complexType>
  <complexType name="startType">
    <attribute name="address" type="string"/>
    <attribute name="state" type="string"/>
    <attribute name="zip" type="string"/>
    <attribute name="country" type="string"/>
  </complexType>
  <complexType name="endType">
    <attribute name="address" type="string"/>
    <attribute name="state" type="string"/>
    <attribute name="zip" type="string"/>
    <attribute name="country" type="string"/>
  </complexType>
  <complexType name="totalEstTimeType">
    <attribute name="hours" type="integer"/>
    <attribute name="minutes" type="integer"/>
  </complexType>
  <complexType name="totalEstDistanceType">
    <attribute name="length" type="decimal"/>
  </complexType>
  <complexType name="directionPointType">
    <choice maxOccurs="unbounded">
      <element ref="d:startOutGoing"/>
      <element ref="d:on"/>
      <element ref="d:turnLeftOnto"/>
      <element ref="d:turnRightOnto"/>
      <element ref="d:turnSlightLeftOnto"/>
      <element ref="d:turnSlightRightOnto"/>
      <element ref="d:mergeOnto"/>
      <element ref="d:becomes"/>
      <element ref="d:takeThe"/>
      <element ref="d:toward"/>
      <element ref="d:via"/>
      <element ref="d:continueToFollow"/>
      <element ref="d:endAt"/>
    </choice>
    <attribute name="length" type="decimal"/>
  </complexType>

  <element name="before" type="string"/>
  <element name="after" type="string"/>
  <element name="onThe" type="d:onTheType"/>
  <element name="exit" type="string"/>
  <element name="ramp" type="string"/>
  
  <complexType name="becomesType">
    <sequence>
      <element ref="d:before"/>
      <element ref="d:after"/>
    </sequence>
  </complexType>
  <complexType name="takeTheType">
    <choice>
      <sequence>
        <element ref="d:ramp"/>
        <choice maxOccurs="unbounded">
          <element ref="d:toward"/>
          <element ref="d:onThe"/>
        </choice>
      </sequence>
      <sequence>
        <element ref="d:exit"/>
        <choice maxOccurs="unbounded">
          <element ref="d:toward"/>
          <element ref="d:onThe"/>
        </choice>
      </sequence>
    </choice>
  </complexType>
  <simpleType name="onTheType">
    <restriction base="string">
      <enumeration value="left"/>
      <enumeration value="right"/>
    </restriction>
  </simpleType>
</schema>
\end{lstlisting}
